import { Inject, Provide } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { In, Repository } from 'typeorm';
import { User } from '@entity/framework/system/SysUser';
import {
  UpdateStudentDto,
  QueryStudentDto,
  createStudentUserDto,
} from '@dto/student.dto';
import { StudentEntity } from '@entity/user/student.entity';
import { resBuild } from '../utils/resBuild';
import { getOperator, isEmpty } from '../utils';
import { genHashPsw } from '@utils/password';
import { SysUserRole } from '@entity/framework/system/SysUserRole';
import { SysDept } from '@entity/framework/system/SysDept';
import { GradeEntity } from '@entity/grade.entity';
import { MajorEntity } from '@entity/major.entity';

@Provide()
export class StudentDao {
  @Inject()
  ctx: Context;
  @InjectEntityModel(StudentEntity)
  studentEntityRep: Repository<StudentEntity>;

  @InjectEntityModel(User)
  userEntity: Repository<User>;

  @InjectEntityModel(SysUserRole)
  protected userRoleEntity: Repository<SysUserRole>;

  @InjectEntityModel(SysDept)
  sysDeptEntityRep: Repository<SysDept>;

  @InjectEntityModel(GradeEntity)
  gradeEntityRep: Repository<GradeEntity>;

  @InjectEntityModel(MajorEntity)
  majorEntityRep: Repository<MajorEntity>;



  async create(createStudentDto: createStudentUserDto) {
    await this.studentEntityRep.manager.transaction(async manager => {
      const userRepo = manager.getRepository(User);
      const studentRepo = manager.getRepository(StudentEntity);
      const userRoleRepo = manager.getRepository(SysUserRole);

      //登录账号
      const userName = createStudentDto.stuId;
      if (!userName) {
        throw new Error('学生学号(stuId)不能为空');
      }

      //学号查重
      const existUser = await userRepo.findOne({ where: { userName } });
      if (existUser) {
        throw new Error(`登录账号(学号)已存在: ${userName}`);
      }
      const digits = (userName || '').replace(/\D/g, '');
      const defaultPwd = digits.length >= 6 ? digits.slice(-6) : (userName || '').slice(-6) || '123456'; //创建系统用户
      const newUser = userRepo.create({
        userName,
        nickName: createStudentDto.nickName || userName,
        password: genHashPsw(defaultPwd),
        email: createStudentDto.email || '',
        phonenumber: createStudentDto.phonenumber || '',
        sex: createStudentDto.sex,
        deptId: createStudentDto.deptId,
        remark: createStudentDto.remark,
      });
      newUser.setCreateBy(getOperator(this.ctx));
      const savedUser = await userRepo.save(newUser);

      //绑定角色
      if (createStudentDto.roleIds && createStudentDto.roleIds.length > 0) {
        const list = createStudentDto.roleIds.map(roleId => ({
          userId: savedUser.userId,
          roleId,
        }));
        await userRoleRepo.save(list);
      }

      // 创建学生并绑定 userId（显式指定Partial类型，避免命中数组重载）
      const student = studentRepo.create({
        userId: savedUser.userId,
        stuId: createStudentDto.stuId,
        email: createStudentDto.email,
        summary: createStudentDto.summary,
        gradeId: createStudentDto.gradeId,
        majorId: createStudentDto.majorId,
        remark: createStudentDto.remark,
        status: createStudentDto.status || '0',
        delFlag: '0',
      } as Partial<StudentEntity>);
      student.setCreateBy(getOperator(this.ctx));
      student.setUpdateBy(getOperator(this.ctx));
      await studentRepo.save(student);
    });

    return resBuild.success();
  }

  async list(query: QueryStudentDto) {
    // 构建基础查询条件的函数
    const qb = this.studentEntityRep
      .createQueryBuilder('stu')
      .leftJoinAndSelect('stu.user', 'user')
      .leftJoinAndSelect('user.dept', 'dept')
      .leftJoinAndSelect('stu.grade', 'grade')
      .leftJoinAndSelect('stu.major', 'major')
    if (!isEmpty(query.userId)) {
      qb.andWhere('stu.userId = :userId', { userId: query.userId });
    }
    if (!isEmpty(query.stuId)) {
      qb.andWhere('stu.stuId ILIKE :stuId', { stuId: `%${query.stuId}%` });
    }
    if (!isEmpty(query.email)) {
      qb.andWhere('stu.email = :email', { email: query.email });
    }
    if (!isEmpty(query.nickName)) {
      qb.andWhere('usr.nickName ILIKE :nickName', { nickName: `%${query.nickName}%` });
    }
    if (!isEmpty(query.summary)) {
      qb.andWhere('stu.summary = :summary', { summary: query.summary });
    }
    if (!isEmpty(query.gradeId)) {
      qb.andWhere('stu.gradeId = :gradeId', { gradeId: query.gradeId });
    }
    if (!isEmpty(query.majorId)) {
      qb.andWhere('stu.majorId = :majorId', { majorId: query.majorId });
    }
    if (!isEmpty(query.status)) {
      qb.andWhere('stu.status = :status', { status: query.status });
    }

    // 分页
    if (query.pageNum && query.pageSize) {
      qb.skip((query.pageNum - 1) * query.pageSize).take(query.pageSize);
    }

    // 排序
    qb.addOrderBy('stu.createTime', 'DESC');

    const [rows, total] = await qb.getManyAndCount();

    return resBuild.list(rows, total);
  }

  async detail(studentId: number) {
    const qb = this.studentEntityRep
      .createQueryBuilder('stu')
      .leftJoin(User, 'usr', 'usr.userId = stu.userId')
      .where('stu.studentId = :studentId', { studentId })
      .andWhere('stu.delFlag = :delFlag', { delFlag: '0' });

    // 学生字段
    qb.addSelect('stu.studentId', 'studentId');
    qb.addSelect('stu.userId', 'userId');
    qb.addSelect('stu.stuId', 'stuId');
    qb.addSelect('stu.email', 'email');
    qb.addSelect('stu.summary', 'summary');
    qb.addSelect('stu.gradeId', 'gradeId');
    qb.addSelect('stu.majorId', 'majorId');
    qb.addSelect('stu.remark', 'remark');
    qb.addSelect('stu.status', 'status');

    // 用户字段
    qb.addSelect('usr.userName', 'userName');
    qb.addSelect('usr.nickName', 'nickName');
    qb.addSelect('usr.deptId', 'deptId');
    qb.addSelect('usr.email', 'userEmail');
    qb.addSelect('usr.phonenumber', 'phonenumber');
    qb.addSelect('usr.sex', 'sex');
    qb.addSelect('usr.status', 'userStatus');

    const row = await qb.getRawOne();
    return resBuild.data(row);
  }

  async update(updateStudentDto: UpdateStudentDto) {
    await this.studentEntityRep.manager.transaction(async manager => {
      const studentRepo = manager.getRepository(StudentEntity);
      const userRepo = manager.getRepository(User);
      const userRoleRepo = manager.getRepository(SysUserRole);

      const { studentId } = updateStudentDto;
      const existStudent = await studentRepo.findOneBy({ studentId });
      if (!existStudent) {
        throw new Error('学生记录不存在');
      }

      const userId = existStudent.userId;
      if (userId) {
        const body: any = updateStudentDto as any;
        const userPatch: any = {};
        if (typeof body.nickName !== 'undefined') userPatch.nickName = body.nickName;
        if (typeof body.email !== 'undefined') userPatch.email = body.email;
        if (typeof body.phonenumber !== 'undefined') userPatch.phonenumber = body.phonenumber;
        if (typeof body.sex !== 'undefined') userPatch.sex = body.sex;
        if (typeof body.deptId !== 'undefined') userPatch.deptId = body.deptId;
        if (typeof body.status !== 'undefined') userPatch.status = body.status;
        if (typeof body.remark !== 'undefined') userPatch.remark = body.remark;

        if (Object.keys(userPatch).length > 0) {
          const tempUser = userRepo.create({ userId, ...userPatch } as Partial<User>);
          tempUser.setUpdateBy(getOperator(this.ctx));
          await userRepo.save(tempUser);
        }

        // 更新绑定角色（若提供 roleIds）
        if (Array.isArray(body.roleIds)) {
          await userRoleRepo.delete({ userId });
          if (body.roleIds.length > 0) {
            const list = body.roleIds.map((roleId: number) => ({ userId, roleId }));
            await userRoleRepo.save(list);
          }
        }
      }
      const body: any = updateStudentDto as any;
      const studentPatch: Partial<StudentEntity> = { studentId };
      if (typeof body.stuId !== 'undefined') studentPatch.stuId = body.stuId;
      if (typeof body.email !== 'undefined') studentPatch.email = body.email;
      if (typeof body.summary !== 'undefined') studentPatch.summary = body.summary;
      if (!isEmpty(body.gradeId)) studentPatch.gradeId = Number(body.gradeId);
      if (!isEmpty(body.majorId)) studentPatch.majorId = Number(body.majorId);
      if (typeof body.remark !== 'undefined') studentPatch.remark = body.remark;
      if (typeof body.status !== 'undefined') studentPatch.status = body.status;
      const entity = studentRepo.create(studentPatch);
      entity.setUpdateBy(getOperator(this.ctx));
      await studentRepo.save(entity);
    });

    return resBuild.success();
  }

  async remove(studentIds: Array<number>) {
    await this.studentEntityRep.manager.transaction(async manager => {
      const studentRepo = manager.getRepository(StudentEntity);
      const userRepo = manager.getRepository(User);
      const userRoleRepo = manager.getRepository(SysUserRole);

      // 先拿到关联的 userId 列表
      const rows = await studentRepo.find({
        where: { studentId: In(studentIds) },
        select: ['userId'],
      });
      const userIds = rows.map(r => r.userId).filter(id => typeof id === 'number');

      // 删除学生
      await studentRepo.delete({ studentId: In(studentIds) });

      // 删除用户关联和用户本身
      if (userIds.length > 0) {
        await userRoleRepo.delete({ userId: In(userIds) });
        await userRepo.delete({ userId: In(userIds) });
      }
    });

    return resBuild.success();
  }

  /**
   * 根据学号查找学生（包含用户信息）
   */
  async findByStuId(stuId: string) {
    const student = await this.studentEntityRep
      .createQueryBuilder('stu')
      .leftJoin(User, 'usr', 'usr.userId = stu.userId')
      .where('stu.stuId = :stuId', { stuId })
      .andWhere('stu.delFlag = :delFlag', { delFlag: '0' })
      .addSelect('stu.studentId', 'studentId')
      .addSelect('stu.userId', 'userId')
      .getRawOne();
    return student;
  }

  /**
   * 批量创建或更新学生（用于导入）
   */
  async batchImport(students: any[], updateSupport: boolean) {
    const results = {
      successCount: 0,
      failCount: 0,
      failMessages: [] as string[],
    };

    await this.studentEntityRep.manager.transaction(async manager => {
      const userRepo = manager.getRepository(User);
      const studentRepo = manager.getRepository(StudentEntity);
      const userRoleRepo = manager.getRepository(SysUserRole);

      for (const studentData of students) {
        try {
          // 查找是否已存在
          const existingStudent = await studentRepo
            .createQueryBuilder('stu')
            .leftJoin(User, 'usr', 'usr.userId = stu.userId')
            .where('stu.stuId = :stuId', { stuId: studentData.stuId })
            .andWhere('stu.delFlag = :delFlag', { delFlag: '0' })
            .select(['stu.studentId', 'stu.userId', 'usr.userId'])
            .getRawOne();

          if (existingStudent && !updateSupport) {
            // 存在且不支持更新，跳过
            results.failMessages.push(`学号${studentData.stuId}已存在，跳过导入`);
            results.failCount++;
            continue;
          }

          if (existingStudent && updateSupport) {
            // 更新逻辑
            const userId = existingStudent.stu_userId;
            const studentId = existingStudent.stu_studentId;

            // 更新用户表
            await userRepo.update(
              { userId },
              {
                nickName: studentData.nickName,
                email: studentData.email || '',
                deptId: studentData.deptId,
                updateBy: getOperator(this.ctx),
                updateTime: new Date(),
              }
            );

            // 更新学生表
            await studentRepo.update(
              { studentId },
              {
                email: studentData.email || '',
                summary: studentData.summary || '',
                gradeId: studentData.gradeId,
                majorId: studentData.majorId,
                updateBy: getOperator(this.ctx),
                updateTime: new Date(),
              }
            );

            // 确保用户有学生角色（roleId = 5）
            const existingRole = await userRoleRepo.findOne({
              where: { userId, roleId: 5 },
            });
            if (!existingRole) {
              await userRoleRepo.save({ userId, roleId: 5 });
            }

            results.successCount++;
          } else {
            // 新增逻辑
            const userName = studentData.stuId;
            const digits = (userName || '').replace(/\D/g, '');
            const defaultPwd =
              digits.length >= 6
                ? digits.slice(-6)
                : (userName || '').slice(-6) || '123456';

            // 创建用户
            const newUser = userRepo.create({
              userName,
              nickName: studentData.nickName,
              password: genHashPsw(defaultPwd),
              email: studentData.email || '',
              deptId: studentData.deptId,
            });
            newUser.setCreateBy(getOperator(this.ctx));
            const savedUser = await userRepo.save(newUser);

            // 绑定学生角色（roleId = 5）
            await userRoleRepo.save({
              userId: savedUser.userId,
              roleId: 5,
            });

            // 创建学生
            const student = studentRepo.create({
              userId: savedUser.userId,
              stuId: studentData.stuId,
              email: studentData.email,
              summary: studentData.summary,
              gradeId: studentData.gradeId,
              majorId: studentData.majorId,
              status: studentData.status || '0',
              delFlag: '0',
            } as Partial<StudentEntity>);
            student.setCreateBy(getOperator(this.ctx));
            student.setUpdateBy(getOperator(this.ctx));
            await studentRepo.save(student);

            results.successCount++;
          }
        } catch (error) {
          results.failCount++;
          results.failMessages.push(
            `学号${studentData.stuId}导入失败：${error.message}`
          );
        }
      }
    });

    return results;
  }

}
